
import subprocess
import re
import random
import winreg 
import platform
# 修改网卡地址需要管理员权限


def get_device():
    print('===========================================================')
    index_list = range(len(network_adapter))
    for index in index_list:
        print(index, ': ', network_adapter[index])

    index = int(input('输入要改变的网卡地址的序号: '))
    while index not in index_list:
        index = int(input('Wrong input! Please input again: '))

    return index, network_adapter[index]

def yield_mac():
    char_list = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'a', 'b', 'c', 'd', 'e', 'f']
    return ''.join(random.sample(char_list, 12))

# 生成一个新的网卡地址
def get_mac_address():
    mac_address = yield_mac()
    return '-'.join([g.zfill(2) for g in MAC_ADDRESS_RE.match(mac_address).groups()]).upper()

# 重启网卡适配器
def restart_adapter(index):
   
    if platform.release() == 'XP':
        # description, adapter_name, address, current_address = find_interface(device)
        cmd = "devcon hwids =net"
        print(cmd)
        # try:
        #     result = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
        # except FileNotFoundError:
        #     raise
        # query = '(' + target_device + '\r\n\s*.*:\r\n\s*)PCI\\\\(([A-Z]|[0-9]|_|&)*)'
        # query = query.encode('ascii')
        # match = re.search(query, result)
        # cmd = 'devcon restart "PCI\\' + str(match.group(2).decode('ascii')) + '"'
        # subprocess.check_output(cmd, stderr=subprocess.STDOUT)
    else:
        cmd = "wmic path win32_networkadapter where index=" + str(index) + " call disable"
        subprocess.check_output(cmd)
        cmd = "wmic path win32_networkadapter where index=" + str(index) + " call enable"
        subprocess.check_output(cmd)



# 重置网卡地址
def set_mac_address(new_mac):

    # Locate adapter's registry and update network address (mac)
    reg_hdl = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
    key = winreg.OpenKey(reg_hdl, WIN_REGISTRY_PATH)
    info = winreg.QueryInfoKey(key)

    # Find adapter key based on sub keys
    adapter_key = None
    adapter_path = None
    target_index = -1

    for index in range(info[0]):
        subkey = winreg.EnumKey(key, index)
        print(subkey)

        path = WIN_REGISTRY_PATH + "\\" + subkey
        if subkey == 'Properties':
            break

        # Check for adapter match for appropriate interface
        new_key = winreg.OpenKey(reg_hdl, path)
        try:
            adapterDesc = winreg.QueryValueEx(new_key, "DriverDesc")
            if adapterDesc[0] == target_device:
                adapter_path = path
                target_index = index
                break
            else:
                winreg.CloseKey(new_key)
        except (WindowsError) as err:
            if err.errno == 2:  # register value not found, ok to ignore
                pass
            else:
                raise err

    if adapter_path is None:
        print('Device not found.')
        winreg.CloseKey(key)
        winreg.CloseKey(reg_hdl)
        return

    # Registry path found update mac addr
    adapter_key = winreg.OpenKey(reg_hdl, adapter_path, 0, winreg.KEY_WRITE)
    winreg.SetValueEx(adapter_key, "NetworkAddress", 0, winreg.REG_SZ, new_mac)
    winreg.CloseKey(adapter_key)
    winreg.CloseKey(key)
    winreg.CloseKey(reg_hdl)

    # Adapter must be restarted in order for change to take affect
    # print 'Now you should restart your netsh'
    restart_adapter(target_index)

WIN_REGISTRY_PATH = "SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}"
MAC_ADDRESS_RE = re.compile(r"""
    ([0-9A-F]{1,2})[:-]?
    ([0-9A-F]{1,2})[:-]?
    ([0-9A-F]{1,2})[:-]?
    ([0-9A-F]{1,2})[:-]?
    ([0-9A-F]{1,2})[:-]?
    ([0-9A-F]{1,2})
    """,
    re.I | re.VERBOSE
)

# 1.读取物理地址
mac_info = subprocess.check_output('GETMAC /v /FO list', stderr=subprocess.STDOUT).decode('gbk')
network_adapter = re.findall(r'\r\n网络适配器:\s+(.+?)\r\n物理地址', mac_info)
mac_address = re.findall(r'\r\n物理地址:\s+(.+?)\r\n传输名称', mac_info)
name_mac_dict = dict(zip(network_adapter, mac_address))
print(name_mac_dict)
# 2.选择需要修改的网卡
index, target_device = get_device()
print(f'当前设备是: {target_device}')
# 3.随机生成一个网卡地址
new_mac_address = get_mac_address()
print('新的网卡地址', new_mac_address)
# 4.设置网卡地址
set_mac_address(new_mac_address)
# 5.查看效果
new_info = subprocess.check_output('GETMAC /v /FO list', stderr=subprocess.STDOUT).decode('gbk')
print(new_info)
print('完成 ...')
# if input('Want to reset? (yes / no)').lower() in ['yes', 'y']:
#     set_mac_address(name_mac_dict[target_device])
#     new_info = subprocess.check_output('GETMAC /v /FO list', stderr=subprocess.STDOUT).decode('gbk')
#     print(new_info)
